/**********************************************************************************************/
/* FBL_Starter_Win.cpp                                                 						  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#include <VShared/FBL/publ/Headers/StdAfx.h>

#include <VShared/FBL/publ/Starter/FBL_Starter.h>
#include <VShared/FBL/publ/Util_classes/FBL_String.h>


/**********************************************************************************************/
#if FBL_WIN

#include <shlobj.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
/** Returns packed version of Windows Shell DLL. */
FBL_SHARED_EXP LONG GetShellVersion ();


/**********************************************************************************************/
const char* GetKernelDllName( void );
const char* GetClientDllName( void );

typedef HRESULT (__stdcall *SHGetFolderPathPfn)(
	HWND hwndOwner,
    int nFolder,
    HANDLE hToken,
    DWORD dwFlags,
    LPTSTR pszPath
);



/**********************************************************************************************/
void FindComponentsFolder( char* outPath )
{
#ifdef __MWERKS__
	const char* p1 = "\\Paradigma Software\\VComponents_Win_CW\\";
	const char* p2 = "C:\\Program Files\\Paradigma Software\\VComponents_Win_CW\\";
#else
	const char* p1 = "\\Paradigma Software\\VComponents_Win_VC\\";
	const char* p2 = "C:\\Program Files\\Paradigma Software\\VComponents_Win_VC\\";
#endif // __MWERKS__

	LONG v = GetShellVersion();
	if( v >= MAKELONG(5, 0) )
	{
		/*char buf[256];
		sprintf(buf, "Shell version: %d.%d", HIWORD(v), LOWORD(v));
		MessageBox(NULL, buf, "Info", MB_OK | MB_ICONINFORMATION);*/

		HMODULE hShell = LoadLibrary("shell32.dll");
		if( hShell )
		{
			SHGetFolderPathPfn pfn = (SHGetFolderPathPfn)::GetProcAddress(hShell, "SHGetFolderPathA");
			if( pfn )
			{
				if( SUCCEEDED(pfn(NULL, CSIDL_PROGRAM_FILES, NULL, 0, outPath)) ) 
					::strcat( outPath, p1 );
				else
				{
					// Fallback to the default path.
					::strcpy( outPath, p2 );
				}
			}
			else
			{
				// Fallback to the default path.
				::strcpy( outPath, p2 );
			}

			FreeLibrary(hShell);
		}
		else
		{
			// Fallback to the default path.
			::strcpy( outPath, p2 );
		}

		//MessageBox(NULL, "After calling SHGetFolderPathA()", "Info", MB_OK | MB_ICONINFORMATION);
	}
	else
	{
		// Fallback to the default path.
		::strcpy( outPath, p2 );
	}
}


/**********************************************************************************************/
extern "C" void InitBackpointers( void );


/**********************************************************************************************/
void Init_ValentinaDlls( bool inUseClientStrings )
{
#if FBL_STATIC

	argused1( inUseClientStrings );
	InitBackpointers();

#else

	// Kernel-dll string-factory has priority.
	if( String::sFactory && inUseClientStrings )
		return;

	HMODULE hDLL;
	
	// Try to load local implementation.
	if( inUseClientStrings || (hDLL = LoadLibrary(GetKernelDllName())) == NULL )
	{
		// Try to load client implementation.
		if( !(hDLL = LoadLibrary(GetClientDllName())) )
		{
			// CRITICAL SITUATION: neither kernel nor client dll was not found!
			// Valentina cannot continue to work.
			// FIXME: throw exception!
			int a = 2;
			a += 1;
			return;
		}
	}

	// --------------------------------
	// Get init callbacks function.
	typedef void (*InitBackpointers_PTR)( void );
	InitBackpointers_PTR pfn;

	// Store reference to the function and call it:
	pfn = (InitBackpointers_PTR) GetProcAddress( hDLL, "InitBackpointers" );
	pfn();

#endif // FBL_STATIC
}


/**********************************************************************************************/
FBL_End_Namespace

#endif // FBL_WIN
